package com.shuosen.gmall.cart.service.impl;

import com.alibaba.dubbo.config.annotation.Reference;
import com.alibaba.dubbo.config.annotation.Service;
import com.alibaba.fastjson.JSON;
import com.shuosen.gmall.bean.CartInfo;
import com.shuosen.gmall.bean.SkuInfo;
import com.shuosen.gmall.cart.CartConst;
import com.shuosen.gmall.cart.mapper.CartInfoMapper;
import com.shuosen.gmall.config.RedisUtil;
import com.shuosen.gmall.service.CartService;
import com.shuosen.gmall.service.ManageService;
import org.springframework.beans.factory.annotation.Autowired;
import redis.clients.jedis.Jedis;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;

@Service
public class CartServiceImpl  implements CartService {

    //需要调用mapper
    @Autowired
    private CartInfoMapper cartInfoMapper ;


    @Reference
    private ManageService manageService  ;

    @Autowired
    private RedisUtil redisUtil  ;

    /***
     *  添加购物车
     *
     * @param skuId  商品id
     * @param userId  用户id
     * @param skuNum  商品数量
     */
    @Override
    public void addToCart(String skuId, String userId, Integer skuNum) {
        /***
         * 1：添加的时候，如果购物车没有该商品，则直接添加
         * 2：如果购物车中有该商品数量相加
         * 3：添加到redis中
         *
         */
        CartInfo cartInfo = new CartInfo() ;
        cartInfo.setSkuId(skuId);
        cartInfo.setUserId(userId);
        CartInfo cartInfoExist = cartInfoMapper.selectOne(cartInfo);
        //判断购物车中是否有该商品
        if(cartInfoExist!=null ){
            //商品数量相加
            cartInfoExist.setSkuNum(skuNum+cartInfoExist.getSkuNum());
            //将实时价格赋值
            cartInfoExist.setSkuPrice(cartInfoExist.getCartPrice());
            //添加到数据库中
            cartInfoMapper.updateByPrimaryKeySelective(cartInfoExist);
            //更新redis
        }else{
            //调用getSKuInfo
            SkuInfo skuInfo = manageService.getSkuInfo(skuId);
            //直接添加到cartInfo
            CartInfo cartInfo1 = new CartInfo();
            cartInfo1.setSkuId(skuId);
            cartInfo1.setCartPrice(skuInfo.getPrice());
            cartInfo1.setSkuPrice(skuInfo.getPrice());
            cartInfo1.setSkuName(skuInfo.getSkuName());
            cartInfo1.setImgUrl(skuInfo.getSkuDefaultImg());
            cartInfo1.setUserId(userId);
            cartInfo1.setSkuNum(skuNum);

            //保存到数据库
            cartInfoMapper.insertSelective(cartInfo1);

            cartInfoExist=cartInfo1;
        }

        Jedis jedis = redisUtil.getJedis();
        //定义key
        String cartKey = CartConst.USER_KEY_PREFIX+userId+CartConst.USER_CART_KEY_SUFFIX  ;

        jedis.hset(cartKey,skuId, JSON.toJSONString(cartInfoExist));

        //细节处理! 更改用户的过期时间.
        String userKey = CartConst.USER_KEY_PREFIX + userId + CartConst.USERINFOKEY_SUFFIX;

        jedis.expire(userKey,60*60*24);

        //获取用户key的过期时间
        Long ttl = jedis.ttl(userKey);

        //京东 一般不会设置过期时间
        //case 1: 设置 购物车的过期时间
        //case 2:设置过期时间与用户存储缓存的时间保持一致
        //case 3：智能化  大数据 一起连用
        jedis.expire(cartKey,ttl.intValue());

        jedis.close();

    }

    @Override
    public List<CartInfo> mergeToCartList(List<CartInfo> cartListFromCookie, String userId) {
        List<CartInfo> cartInfoListDB =  cartInfoMapper.selectCartListWithCurPrice(userId);
        // 循环开始匹配
        for (CartInfo cartInfoCK : cartListFromCookie) {
             boolean isMatch = false  ;
            for (CartInfo cartInfoDB : cartInfoListDB) {
                if(cartInfoDB.getSkuId().equals(cartInfoCK.getSkuId())){
                   cartInfoDB.setSkuNum(cartInfoCK.getSkuNum()+cartInfoDB.getSkuNum());
                   cartInfoMapper.updateByPrimaryKeySelective(cartInfoDB);
                   isMatch = true  ;
                }

            }
            //数据库中没有购物车 ，则直接将cookie中购物车添加到数据库
            if(!isMatch){
                 cartInfoCK.setUserId(userId);
                 cartInfoMapper.insertSelective(cartInfoCK);
            }
        }
        //重新在数据中查询并返回数据 
        List<CartInfo> cartInfoList =  loadCartCache(userId);

        for (CartInfo cartInfo : cartInfoList) {
            for (CartInfo info : cartListFromCookie) {
                if(cartInfo.getSkuId().equals(info.getSkuId())){
                    //只有被勾选的才会进行更改
                    if(info.getIsChecked().equals("1")){
                        cartInfo.setIsChecked(info.getIsChecked());
                        //更新redis中的ischecked
                        checkCart(cartInfo.getSkuId(),info.getIsChecked(),userId);
                    }
                }
            }

        }
        return cartInfoList;
    }

    private List<CartInfo> loadCartCache(String userId) {
        //显示实时价格
        /***
         *
         * 实时价格指的是 CartInfo.skuPrice=xxx?
         */
        List<CartInfo> cartInfoList = cartInfoMapper.selectCartListWithCurPrice(userId);

        //cartInfoList 是否为空
        if(cartInfoList==null || cartInfoList.size()==0){
            return null ;
        }

        //判断cartInfoList是否为空
        Jedis jedis = redisUtil.getJedis();
        String userCartKey = CartConst.USER_KEY_PREFIX+userId+CartConst.USER_CART_KEY_SUFFIX ;
        HashMap<String,String>  map = new HashMap<>();
        //循环遍历将数据添加到缓存
        for (CartInfo cartInfo : cartInfoList) {
            map.put(cartInfo.getSkuId(),JSON.toJSONString(cartInfo));
        }
        jedis.hmset(userCartKey,map);
        //关闭jedis
        return cartInfoList;
    }

    @Override
    public List<CartInfo> getCartList(String userId) {
        List<CartInfo> cartInfoList = new ArrayList<>();
        /***
         *
         * 1：先从缓存中获取数据
         * 2：如果缓存中没有，则去数据库中获取 ，并将数据保存到缓存中！
         *
         */
        Jedis jedis = redisUtil.getJedis();
        //定义key
        // 定义key
        String cartKey = CartConst.USER_KEY_PREFIX+userId+CartConst.USER_CART_KEY_SUFFIX;
        List<String> cartJson = jedis.hvals(cartKey);
        if(cartJson!=null && cartJson.size()>0){
            for (String cart : cartJson) {
                CartInfo cartInfo = JSON.parseObject(cart, CartInfo.class);
                cartInfoList.add(cartInfo);
            }
            //显示购物车列表的时候，应该将最新添加的数据显示在最上边 排序 orderby time   不行
            // 做个测试id
            //集合如何排序  collection collections
             //Comparable  内部比较器  Comparator ：外部比较器 比较器
            cartInfoList.sort(new Comparator<CartInfo>() {
                @Override
                public int compare(CartInfo o1, CartInfo o2) {
                    /***
                     * compareTo 内部比较
                     */
                    return o1.getId().compareTo(o2.getId());
                }
            });


        }
        jedis.close();

        return cartInfoList;
    }

    @Override
    public void checkCart(String skuId, String isChecked, String userId) {
        //更新购物车中的isChecked标志
        Jedis jedis = redisUtil.getJedis();
        //取得购物车中的信息
        String userCartKey = CartConst.USER_KEY_PREFIX + userId + CartConst.USER_CART_KEY_SUFFIX;
        String cartJson  = jedis.hget(userCartKey,skuId);
        //将cartJson转换成对象
        CartInfo cartInfo = JSON.parseObject(cartJson, CartInfo.class);
        cartInfo.setIsChecked(isChecked);
        String cartCheckJson = JSON.toJSONString(cartInfo);
        jedis.hset(userCartKey,skuId,cartCheckJson);
        //新增到已选择的购物车
        String userCheckKey =  CartConst.USER_KEY_PREFIX+userId+CartConst.USER_CHECKED_KEY_SUFFIX;
        if(isChecked.equals("1")){
            jedis.hset(userCheckKey,skuId,cartCheckJson) ;
        }else{
            jedis.hdel(userCheckKey,skuId);
        }
        jedis.close();

    }

    @Override
    public List<CartInfo> getCartCheckedList(String userId) {
        List<CartInfo> cartInfoList = new ArrayList<>();
        Jedis jedis = redisUtil.getJedis();
        //取得购物车中的信息
        String userCartKey = CartConst.USER_KEY_PREFIX + userId + CartConst.USER_CART_KEY_SUFFIX;
        List<String>  cartList = jedis.hvals(userCartKey);
       //循环遍历  将集合字符串遍历
        if(cartList!=null && cartList.size() >0  ){
            for (String cart : cartList) {
                CartInfo cartInfo = JSON.parseObject(cart, CartInfo.class);
                cartInfoList.add(cartInfo);
            }
        }
        return cartInfoList;
    }
}
